home *** CD-ROM | disk | FTP | other *** search
/ PsL Monthly 1993 December / PSL Monthly Shareware CD-ROM (December 1993).iso / prgmming / dos / pascal / strngrw.com / STRINGS.DOC < prev    next >
Encoding:
Text File  |  1989-09-09  |  20.1 KB  |  439 lines

  1.                      Turbo Pascal Rexx STRINGS Unit
  2.                 Version 1.2 for Turbo Pascal 4.0, 5.0 & 5.5
  3.  
  4.       STRINGS.TPU is a Turbo Pascal unit containing 29 string-related
  5.       functions implemented in assembler.  These routines are highly
  6. |     optimized (check out the benchmark program) and make extensive use
  7.       of the 80x86 string oriented opcodes.  IBM mainframe hackers will
  8. |     notice that this package is substantially equivalent to the string
  9.       routines available in IBM's Rexx language.
  10.  
  11. |     Three versions are included:  STR40.TPU, STR50.TPU and STR55.TPU
  12. |     for TPas versions 4.0, 5.0 and 5.5, respectively.  Be sure to
  13. |     rename the appropriate file to STRINGS.TPU before usage.
  14.  
  15.                         Function Descriptions
  16.                         ---------------------
  17.  
  18. function left(str:string; width:byte; pad:char):string;
  19.          Returns STR left justified in a field of width WIDTH, padded out
  20.          with PAD characters.
  21.          Ex: left('hello',10,'=') returns 'hello====='
  22.              left('hello there',10,'=') returns 'hello ther'
  23.  
  24. function right(str:string; width:byte; pad:char):string;
  25.          Returns STR right justified in a field of width WIDTH, padded out
  26.          with PAD characters.
  27.          Ex: right('hello',10,'>') returns '>>>>>hello'
  28.              right('hello there',10,'>') returns 'ello there'
  29.  
  30. function center(str:string; width:byte; pad:char):string;
  31.          Returns STR centered in a string of length WIDTH, padded out
  32.          with PAD chars.
  33.          Ex: center('ABC',8,' ') returns '  ABC   '
  34.              center(' ABC ',8,'-') returns '- ABC --'
  35.              center('ABCDE',3,'-') returns 'ABC'
  36.  
  37. function strip(str:string; opt,ch:char):string;
  38.          Strips leading and/or trailing CH characters from STR.
  39.          Setting OPT to L, T or B causes leading, trailing, or both
  40.          leading and trailing characters to be stripped.
  41.          Ex: strip('   abcdef  ','L',' ') returns 'abcdef  '
  42.              strip('   abcdef  ','t',' ') returns '   abcdef'
  43.              strip('   abcdef  ','b',' ') returns 'abcdef'
  44.              strip('++ abcdef +','B','+') returns ' abcdef '
  45.  
  46. function lastpos(findstr,instr:string; start:byte):byte;
  47.          Returns the position of the last occurrance of FINDSTR in INSTR,
  48.          searching backwards from the character position START.  If START
  49.          is 0, the search begins at the end of INSTR.  Returns 0 if the
  50.          string is not found.
  51.          Ex: lastpos('he','he was the best',15) returns 9.
  52.              lastpos('he','he was the best',6) returns 1.
  53.              lastpos('he','he was the best',0) returns 9.
  54.              lastpos('he','he was the best',1) returns 0.
  55.  
  56. function firstpos(findstr,instr:string; start:byte):byte;
  57.          This function was included for completeness.  It works exactly
  58.          the same way as Turbo's built in POS function, except for the
  59.          presence of the START option.  It is equivalent to:
  60.          start-1+pos(findstr,copy(instr,start,length(instr)-start+1));
  61.          except for being more efficient.
  62.          Ex: firstpos('he','he was the best',15) returns 0.
  63.              firstpos('he','he was the best',6) returns 9.
  64.              firstpos('he','he was the best',0) returns 1.
  65.              firstpos('he','he was the best',1) returns 1.
  66. |        The timing benchmark in BENCHMRK.PAS indicates this runs
  67. |        over NINE times faster than Tpas's POS function, on my NEC
  68. |        V20 CPU (a Japanese clone of an 8088).
  69. |        (this will vary with the specific strings involved)
  70.  
  71. function copies(str:string; count:byte):string;
  72.          Returns COUNT copies of STR concatenated together.
  73.          If the length of n(<=count) copies of STR would exceed 255,
  74.          n-1 copies are returned.
  75.          Ex:  copies('----+',4) returns '----+----+----+----+'
  76.  
  77. function overlay(new,str:string; pos:byte; pad:char):string;
  78.          Returns the string STR, overlayed by the string NEW, starting
  79.          at character position POS, padding out STR with PAD characters
  80.          if necessary.
  81.          Ex: overlay('aygu','Ronald Reagan',9,'+') returns 'Ronald Raygun'
  82.              overlay('abc','xyz',6,'+') returns 'xyz++abc'
  83.  
  84. |function instr(new,str:string; pos:byte; pad:char):string;
  85. |        Returns the string STR after insertion of the string NEW,
  86. |        starting at character position POS, padding out STR with PAD
  87. |        characters if necessary.
  88. |        Ex: instr('abcdef','123456',4,'+') returns '123abcdef456'
  89. |            instr('abcdef','123456',10,'+') returns '123456+++abcdef'
  90. |        While having similar function to TPas's INSERT procedure, the
  91. |        timing benchmark in BENCHMRK.PAS indicates instr is about 60%
  92. |        faster.
  93.  
  94. |function delstr(str:string; pos,len:byte):string;
  95. |        Returns the string STR after deletion of LEN characters,
  96. |        starting at character position POS.
  97. |        Ex: delstr('abcdefgh',4,2) returns 'abcfgh'
  98. |            delstr('abcdefgh',4,20) returns 'abc'
  99. |        While having similar function to TPas's DELETE procedure, the
  100. |        timing benchmark in BENCHMRK.PAS indicates delstr is about 50%
  101. |        faster.
  102.  
  103. |function substr(str:string; pos,len:byte):string;
  104. |        Returns a substring from STR, starting at position POS
  105. |        and continuing for LEN characters, or until the end of STR.
  106. |        Ex: substr('1234567890',4,2) returns '45'
  107. |            substr('1234567890',4,20) returns '4567890'
  108. |        This function is identical to TPas's COPY function, and it
  109. |        executes at the same speed.  So why did I include it?  Who
  110. |        knows?  I guess I like typing substr better than typing copy...
  111.  
  112. function uppercase(str:string):string;
  113.          Folds the argument STR to uppercase.
  114.          Ex: uppercase('abcdef123') returns 'ABCDEF123'
  115.  
  116. function lowercase(str:string):string;
  117.          Folds the argument STR to lowercase.
  118.          Ex: lowercase('ABCDEF123') returns 'abcdef123'
  119.  
  120. function words(str:string):byte;
  121.          Returns the number of (blank delimited) words in the string STR.
  122.          Ex: words('two four six      eight') returns 4.
  123.  
  124. function werd(str:string; n:byte):string;
  125.          Returns the N'th (blank delimited) word from the string STR.
  126.          The strange spelling is to avoid conflict with Tpas's WORD type.
  127.          Ex: werd('two     air is humin',3) returns 'is'
  128.              werd('two     air is humin',5) returns ''
  129.  
  130. function subword(str:string; n,count:byte):string;
  131.          Returns COUNT words from STR, starting at the N'th word.
  132.          Embedded blanks are preserved.
  133.          Ex: subword('one two three  four',2,3) returns 'two three  four'
  134.              subword('one two three  four',2,0) returns ''
  135.              subword('one two  three ',2,3) returns 'two  three'
  136.              subword('one two  three ',4,2) returns ''
  137.  
  138. function delword(str:string; n,count:byte):string;
  139.          Returns STR with COUNT words deleted, starting at word N.
  140.          Preceeding blanks are preserved.
  141.          Ex: delword('here   we go again',2,2) returns 'here   again'
  142.  
  143. function pos2word(str:string; pos:byte):byte;
  144.          Returns the number of the word in STR pointed to by POS.  If
  145.          POS points to a blank, the number of the following word is
  146.          returned.  If POS points after the last word or end of STR,
  147.          or POS is 0, then 0 is returned.
  148.          Ex: pos2word('abc def ghi ',4) returns 2.
  149.              pos2word('abc def ghi ',6) returns 2.
  150.              pos2word('abc def ghi ',11) returns 3.
  151.              pos2word('abc def ghi ',12) returns 0.
  152.              pos2word('abc def ghi ',0) returns 0.
  153.  
  154. function word2pos(str:string; wrd:byte):byte;
  155.          Returns the position in STR of the first character in the WRD'th
  156.          word.  If WRD>WORDS(STR) or WRD=0, returns 0.
  157.          Ex: word2pos('  abcd e  fghi jk',2) returns 8.
  158.          Note that this function is equivalent to Rexx's WORDINDEX
  159.          function.
  160.  
  161. function space(str:string; spc:byte):string;
  162.          Returns STR with each word separated by SPC blanks.
  163.          Ex: space('  here  we   go again  ',0) returns 'herewegoagain'
  164.              space('  here  we   go again  ',1) returns 'here we go again'
  165. |        If the length of the output string would exceed 255, the string
  166. |        is truncated at the end of the last whole word which fits.
  167.  
  168. function justify(str:string; len:byte):string;
  169.          Distributes blanks between words in STR so that length(STR)=LEN.
  170.          Ex: justify(' a  b cd  ef ',10)='a b  cd ef'
  171. |        The length of STR should be <= than LEN.
  172. |        This runs about eight times faster than the previous version,
  173. |        which was written in pascal.
  174. |        See usage notes below for important information on usage.
  175.  
  176. function translate(str,intable,outable:string):string;
  177.          Returns STR after translation via the map INTABLE->OUTABLE.
  178.          In other words, each occurrance in STR of the i'th character
  179.          in INTABLE is replaced by the i'th character in OUTABLE.
  180.          Ex: translate('ABC BDE',' BCF','XYZ ') returns 'AYZXYDE'
  181.          INTABLE and OUTABLE should be of the same length.
  182.  
  183. function verify(str,ref:string; opt:char; start:byte):byte;
  184.          Returns the position of the first character in STR (after START)
  185.          which matches/doesn't match a character in REF.  Setting OPT to
  186.          'M' or 'N' returns matching or non-matching character positions,
  187.          respectively.
  188.          Ex: verify('abcd1ef','0123456789','M',0) returns 5.
  189.              verify('123a125','0123456789','n',0) returns 4.
  190.  
  191. function compare(s1,s2:string):byte;
  192.          Compares S1 to S2 and returns the position of the first
  193.          characters which don't match, or 0 if all characters match.
  194.          Ex: compare('hello','hello there') returns 6.
  195.              compare('hello','hexlo') returns 3.
  196.              compare('hello','hello') returns 0.
  197.              compare('','') returns 0.
  198.  
  199. function xrange(c1,c2:char):string;
  200.          Returns a string containing all characters from C1 to C2
  201. |        inclusive.  Note the ordering of C1 & C2 can now be reversed.
  202.          Ex: xrange('a','h') returns 'abcdefgh'
  203. |            xrange('h','a') returns 'hgfedcba'
  204.  
  205. function reverse(str:string):string;
  206.          Returns contents of STR in reverse order.
  207.          Ex: reverse('hello there') returns 'ereht olleh'
  208.  
  209. function abbrev(str,abbr:string; len:byte):boolean;
  210.          Returns true if ABBR is an 'acceptable' abbreviation for STR.
  211.          The criterion is:
  212.             length(ABBR)>=LEN and ABBR=left(STR,length(ABBR),' ')
  213.          LEN should be set <= length(STR).
  214.          Ex: abbrev('DELETE','DEL',3)=true
  215.              abbrev('DELETE','DELY',3)=false
  216.              abbrev('DELETE','DELET',3)=true
  217.              abbrev('DELETE','DELETEX',3)=false
  218.  
  219. function d2x(i:word):xstr;
  220.          (XSTR is defined in the TPU as STRING[4])
  221.          Returns a four byte string equal to the hex representation of I.
  222.          Ex: d2x(255) returns '00FF'
  223.  
  224. function x2d(x:xstr):word;
  225.          Returns the numeric value represented by the xstr X.  Upper
  226.          and lower case A-F are valid on input.  No checking is done for
  227.          the validity of the characters in X, so garbage input gives
  228.          garbage output.  If the validity of X is in doubt, use the
  229.          VERIFY function first:
  230.          validx:=(verify(x,'0123456789ABCDEFabcdef','N')=0);
  231.          Ex: x2d('7F') returns 127.
  232.  
  233.                                  Usage Notes
  234.                                  -----------
  235.  
  236.       Note that Rexx's FIND and WORDLENGTH functions can be readily
  237.       synthesized using functions in this package:
  238.  
  239.       {find returns the number of the word in str1 where str2 starts}
  240.       find(str1,str2) ::= pos2word(str1,firstpos(str2,str1,1))
  241.  
  242.       {wordlength returns the length of a word in str}
  243.       wordlength(str,n) ::= length(word(str,n))
  244.  
  245.       The previous version of justify did an implicit space(str,1) upon
  246.       entry.  However, it turns out that any reasonable text formatting
  247.       algorithm will require that a space() be done BEFORE the call to
  248.       justify (see TXTFMT.PAS for an example) so the implicit call is
  249.       actually redundant, so I got rid of it.  This also allows the
  250.       added flexibility of inserting an extra space after periods (at
  251.       the end of sentences) before calling justify, if you're picky
  252.       about such things.  Justify DOES do an implicit strip(str,'B',' ')
  253.       upon entry.
  254.  
  255. Why the lack of VAR string parameters? (in case you were wondering)
  256.  
  257.       I initially wrote this unit to use VAR string formal parameters in
  258.       the interest of speed, but I've since discovered that when calling
  259.       external assembler routines with value string formal parameters,
  260.       when the actual parameter is a string variable (as opposed to a
  261.       string expression), TP passes a pointer to the ACTUAL variable,
  262.       not a copy of the variable.  While this behavior isn't consistent
  263.       with the pascal standard, assembler isn't pascal, and it does give
  264.       the programmer the best of both worlds:  fast execution and low
  265.       stack overhead when using string variables as parameters, and the
  266.       flexibility of value parameters.  At any rate, string variable
  267.       function parameters are NEVER modified.
  268.  
  269. Differences between releases:
  270.  
  271. Release 1.05:
  272.  
  273.       Converted ABBREV and DELWORD to asm.  Included turbo compiler
  274.       directives {$N-,E-,D-,L-,B-,I-,R-,S+,V-} for optimization.  Added
  275.       PAD parameter to OVERLAY.  Added CHGSTR.  Fixed bug in FIRSTPOS.
  276.       Changed behavior of SUBWORD when COUNT=0, to match Rexx's SUBWORD
  277.       function.
  278.  
  279. Release 1.1:
  280.  
  281.       Compiled for Tpas 5.0.  Modified to cooperate with Tpas's dead
  282.       code elimination feature.  Added X2D & D2X.  Changed JUSTIFY to
  283.       use integer arithmetic for added speed.  Changed name of function
  284.       WORD to WERD to avoid conflict with Tpas's new WORD type.  Added
  285.       type XSTR for use with X2D & D2X.
  286.  
  287. Release 1.11:
  288.  
  289.       Tweaked LEFT, RIGHT, SPACE and COMPARE for optimization.
  290.  
  291. |Release 1.2:
  292. |
  293. |     Added SUBSTR, INSTR & DELSTR.  Converted JUSTIFY to asm.  Got rid
  294. |     of CHGSTR (it didn't seem as useful as I'd first thought, it's not
  295. |     part of standard Rexx, and it was out of place as a pascal routine
  296. |     among asm routines).  Changed truncation behavior in SPACE when
  297. |     output string exceeds 255 chars.  Changed XRANGE to allow reverse
  298. |     ordering of C1 and C2, to produce reversed output.  Included
  299. |     benchmark and test suite programs.  Included TPU versions for TP
  300. |     4.0, 5.0 and 5.5.
  301.  
  302. Examples:
  303.  
  304.       Capitalize the first char in each word in a string S:
  305.       for i:=1 to words(S);
  306.           j:=word2pos(S,i);
  307.           S:=overlay(upcase(S[j]),S,j);
  308.       end;
  309.  
  310.       Find the lowest-ordered alphabetic character in a string STR
  311.       of uppercase characters:
  312.       lochar:=chr(ord('A')+verify(xrange('A','Z'),STR,'M',0)-1);
  313.  
  314.       Find the highest-ordered alphabetic character in a string STR
  315.       of uppercase characters:
  316.       hichar:=
  317.          chr(ord('Z')-verify(xrange('Z','A'),STR,'M',0)+1);
  318.  
  319.       Replace non-alphabetic chars with blanks in a string S:
  320.       S:=translate(S,xrange('!','9')+xrange(':','@')+
  321.              xrange('[','`')+xrange('{',''),left('',33,' '));
  322.       Or:
  323.       S:=translate(S,translate(xrange('!',''),xrange('A','Z')+xrange('a','z'),
  324.              left('',52,' ')),left('',ord('')-ord('!')+1,' '));
  325.  
  326.       Generate a sorted string S consisting of chars between '0' and 'z',
  327.       none of which occur in an alphanumeric string STR:
  328.       S:=space(translate(xrange('0','z'),STR,left('',length(STR),' ')),0);
  329.  
  330.       Generate a sorted string S, each of who's characters occurs at least
  331.       once in an alphanumeric string STR:
  332.       S:=space(translate(xrange('0','z'),translate(xrange('0','z'),
  333.              STR,left('',length(STR),' ')),left('',75,' ')),0);
  334.  
  335.       Permute the characters in a 'MM/DD/YY' date string to allow for
  336.       easy date comparison:
  337.       translate('78312645','12345678','12/25/88') returns '88/12/25'.
  338.  
  339.       A simple text formatting example is in TXTFMT.PAS.
  340.  
  341.  
  342.                              The Fine Print
  343.                              --------------
  344.  
  345.       STRINGS.TPU is copyright 1989 by Richard Winkel.  The ASM & OBJ
  346.       files are available from me for $10 if you send me a formatted
  347.       360K disk in a stamped self addressed mailer.  If you want to
  348.       avoid the hassle, add $3 and I'll buy the floppy, mailer and
  349.       postage.
  350.  
  351. Note: Purchase of the ASM & OBJ files confers an unlimited license to
  352.       incorporate these routines into your own programs for any purpose,
  353.       commercial or otherwise.
  354.  
  355. Send cash, check or money order to:
  356.  
  357.    Richard Winkel
  358.    Route 1, box 193
  359.    Harrisburg, MO.   65256
  360.  
  361. Note: You don't need an assembler to recompile the TPU, as long as
  362.       you have the OBJ files and a Turbo Pascal compiler.
  363.  
  364. Internet address:
  365. MATHRICH@UMCVMB.BITNET,
  366. MATHRICH@UMCVMB.MISSOURI.EDU or
  367. MATHRICH%UMCVMB@CUNYVM.CUNY.EDU
  368.  
  369. ------------------------------- cut here ---------------------------
  370.  
  371.                   Calling Syntax Guide to STRINGS.TPU
  372.  
  373. type xstr=string[4];
  374.  
  375. function abbrev(str,abbr:string; len:byte):boolean;
  376. function center(s:string; width:byte; pad:char):string;
  377. function compare(s1,s2:string):byte;
  378. function copies(str:string; count:byte):string;
  379. function d2x(i:word):xstr;
  380. function delstr(str:string; pos,len:byte):string;
  381. function delword(str:string; n,len:byte):string;
  382. function firstpos(findstr,instr:string; start:byte):byte;
  383. function instr(new,str:string; pos:byte; pad:char):string;
  384. function justify(str:string; len:byte):string;
  385. function lastpos(findstr,instr:string; start:byte):byte;
  386. function left(str:string; width:byte; pad:char):string;
  387. function lowercase(s:string):string;
  388. function overlay(new,str:string; pos:byte; pad:char):string;
  389. function pos2word(s:string; pos:byte):byte;
  390. function reverse(str:string):string;
  391. function right(str:string; width:byte; pad:char):string;
  392. function space(str:string; spc:byte):string;
  393. function strip(s:string; opt,ch:char):string; {opt='L', 'T' or 'B'}
  394. function substr(str:string; pos,len:byte):string;
  395. function subword(str:string; num,count:byte):string;
  396. function translate(str,intable,outable:string):string;
  397. function uppercase(s:string):string;
  398. function verify(str,ref:string; opt:char; start:byte):byte; {opt='M' or 'N'}
  399. function werd(s:string;c:byte):string;
  400. function word2pos(s:string; wrd:byte):byte;
  401. function words(s:string):byte;
  402. function x2d(str:xstr):word;
  403. function xrange(c1,c2:char):string;
  404.  
  405.          ----------------end-of-author's-documentation---------------
  406.  
  407.                         Software Library Information:
  408.  
  409.                    This disk copy provided as a service of
  410.  
  411.                         The Public (Software) Library
  412.  
  413.          We are not the authors of this program, nor are we associated
  414.          with the author in any way other than as a distributor of the
  415.          program in accordance with the author's terms of distribution.
  416.  
  417.          Please direct shareware payments and specific questions about
  418.          this program to the author of the program, whose name appears
  419.          elsewhere in  this documentation. If you have trouble getting
  420.          in touch with the author,  we will do whatever we can to help
  421.          you with your questions. All programs have been tested and do
  422.          run.  To report problems,  please use the form that is in the
  423.          file PROBLEM.DOC on many of our disks or in other written for-
  424.          mat with screen printouts, if possible.  The P(s)L cannot de-
  425.          bug programs over the telephone.
  426.  
  427.          Disks in the P(s)L are updated monthly, so if you did not get
  428.          this disk  directly from the P(s)L,  you should be aware that
  429.          the files in this set may no  longer be the current versions.
  430.  
  431.          For a copy of the latest monthly software library newsletter
  432.          and a list of the 1,900+ disks in the library, call or write
  433.  
  434.                         The Public (Software) Library
  435.                               P.O.Box 35705 - F
  436.                            Houston, TX 77235-5705
  437.                                (713) 665-7017
  438.  
  439.